using LiJ.Common.Core;
using LiJ.Common.Core.Enums;
using LiJ.Common.Extention;
using LiJ.Pay.Ali.Pay.Mos;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LiJ.Pay.Ali.Pay
{
	/// <summary>
	///  支付相关接口
	/// </summary>
	public class ZPayTradeApi : ZPayBaseApi
	{
		/// <inheritdoc />
		public ZPayTradeApi(ZPayConfig config = null)
			: base(config)
		{
		}

		/// <summary>
		/// 预下单（用户扫码付款 - 用户扫商家二维码）
		/// </summary>
		/// <param name="payReq"></param>
		public async Task<ZAddPreTradeResp> AddPrePayTradeAsync(ZAddPreTradeReq payReq)
		{
			return await base.PostApiAsync<ZAddPreTradeReq, ZAddPreTradeResp>("alipay.trade.precreate", "alipay_trade_precreate_response", payReq);
		}

		/// <summary>
		///   下单（商家扫码收款 - 商家扫用户二维码、读取声波发起支付）
		/// </summary>
		/// <param name="payReq"></param>
		public async Task<ZAddPayTradeResp> AddPayTradeAsync(ZAddPayTradeReq payReq)
		{
			return await base.PostApiAsync<ZAddPayTradeReq, ZAddPayTradeResp>("alipay.trade.pay", "alipay_trade_pay_response", payReq);
		}

		/// <summary>
		/// 下单（支付宝内部JS唤起支付
		/// </summary>
		/// <param name="payReq"></param>
		public async Task<ZAddOfficialTradeResp> GetOfficialTradeAsync(ZAddOfficialTradeReq payReq)
		{
			if (string.IsNullOrEmpty(payReq.notify_url))
			{
				payReq.notify_url = base.ApiConfig.NotifyUrl;
			}
			return await base.PostApiAsync<ZAddOfficialTradeReq, ZAddOfficialTradeResp>("alipay.trade.create", "alipay_trade_create_response", payReq);
		}

		/// <summary>
		/// 获取客户端App唤起支付请求内容
		/// </summary>
		/// <param name="req"></param>
		public ResultMo<string> GetAppTradeContent(ZAddAppTradeReq req)
		{
			if (string.IsNullOrEmpty(req.notify_url))
			{
				req.notify_url = base.ApiConfig.NotifyUrl;
			}
			ResultMo<IDictionary<string, string>> reqBodyDics = base.GetReqBodyDics("alipay.trade.app.pay", req);
			if (reqBodyDics.IsSuccess())
			{
				return new ResultMo<string>(ZPayBaseApi.ConvertDicToEncodeReqBody(reqBodyDics.Data));
			}
			return reqBodyDics.ConvertToResultOnly<string>();
		}

		/// <summary>
		/// 获取PC端转到支付宝收银台请求内容
		/// </summary>
		/// <param name="req"></param>
		public ResultMo<string> GetPageTradeContent(ZAddPageTradeReq req)
		{
			if (string.IsNullOrEmpty(req.notify_url))
			{
				req.notify_url = base.ApiConfig.NotifyUrl;
			}
			ResultMo<IDictionary<string, string>> reqBodyDics = base.GetReqBodyDics("alipay.trade.page.pay", req);
			if (reqBodyDics.IsSuccess())
			{
				return new ResultMo<string>(this.BuildFormHtml(reqBodyDics.Data));
			}
			return reqBodyDics.ConvertToResultOnly<string>();
		}

		/// <summary>
		/// 获取客户端Wap唤起支付请求内容
		/// </summary>
		/// <param name="req"></param>
		public ResultMo<string> GetWapTradeContent(ZAddWapTradeReq req)
		{
			if (string.IsNullOrEmpty(req.notify_url))
			{
				req.notify_url = base.ApiConfig.NotifyUrl;
			}
			ResultMo<IDictionary<string, string>> reqBodyDics = base.GetReqBodyDics("alipay.trade.wap.pay", req);
			if (reqBodyDics.IsSuccess())
			{
				return new ResultMo<string>(this.BuildFormHtml(reqBodyDics.Data));
			}
			return reqBodyDics.ConvertToResultOnly<string>();
		}

		private string BuildFormHtml(IDictionary<string, string> dics)
		{
			long num = DateTime.Now.ToUtcSeconds();
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(string.Format("<form id='{0}' name='alipaysubmit' action='{1}?charset={2}' method='POST'>", num, "https://openapi.alipay.com/gateway.do", base.ApiConfig.Charset));
			foreach (KeyValuePair<string, string> dic in dics)
			{
				stringBuilder.Append(string.Format("<input  name='{0}' value='{1}'/>", dic.Key, dic.Value));
			}
			stringBuilder.Append("<input type='submit' value='submit' style='display:none;'></form>");
			stringBuilder.Append(string.Format("<script>document.forms['{0}'].submit();</script>", num));
			return stringBuilder.ToString();
		}

		/// <summary>
		///   统一收单线下交易查询
		/// </summary>
		/// <param name="queryReq"></param>
		public async Task<ZQueryTradeResp> QueryTradeAsync(ZQueryTradeReq queryReq)
		{
			return await base.PostApiAsync<ZQueryTradeReq, ZQueryTradeResp>("alipay.trade.query", "alipay_trade_query_response", queryReq);
		}

		/// <summary>
		///  撤销交易接口
		/// </summary>
		/// <param name="req"></param>
		public async Task<ZPayCancelResp> CancelTradeAsync(ZPayCancelReq req)
		{
			return await base.PostApiAsync<ZPayCancelReq, ZPayCancelResp>("alipay.trade.cancel", "alipay_trade_cancel_response", req);
		}

		/// <summary>
		///  获取对账单下载地址
		/// </summary>
		/// <param name="req"></param>
		public async Task<ZGetDownloadUrlResp> GetDownloadUrlAsync(ZGetDownloadUrlReq req)
		{
			return await base.PostApiAsync<ZGetDownloadUrlReq, ZGetDownloadUrlResp>("alipay.data.dataservice.bill.downloadurl.query", "alipay_data_dataservice_bill_downloadurl_query_response", req);
		}

		/// <summary>
		///  验证回调接口签名
		/// </summary>
		/// <param name="formDics">表单的字典值</param>
		/// <returns></returns>
		public ResultMo CheckCallBackSign(IDictionary<string, string> formDics)
		{
			if (!formDics.ContainsKey("sign"))
			{
				return new ResultMo(ResultTypes.ParaError, "未发现sign参数");
			}
			string sign = formDics["sign"];
			formDics.Remove("sign");
			formDics.Remove("sign_type");
			SortedDictionary<string, string> source = new SortedDictionary<string, string>(formDics);
			string signContent = string.Join("&", from d in source
			select d.Key + "=" + d.Value.UrlDecode());
			ResultMo resultMo = new ResultMo();
			base.CheckSign(signContent, sign, resultMo);
			return resultMo;
		}
	}
}
